#!/usr/bin/env python

# vPresent is an immersive presentation creation and display application.
# Copyright (C) 2007-2009 by Priority 5 Holdings, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# This is a simple test program for PyOpenSG clustering.
#
# To test it, run 
#   ./ClusterServer.py -geometry 300x300+200+100 -m -w test1 &
#   ./ClusterServer.py -geometry 300x300+500+100 -m -w test2 &
#   ./ClusterClient.py -m -f Data/tie.wrl test1 test2
#
# If you have trouble with multicasting, you can alternatively try
#   ./ClusterServer.py -geometry 300x300+200+100 -w 127.0.0.1:30000 &
#   ./ClusterServer.py -geometry 300x300+500+100 -w 127.0.0.1:30001 &
#   ./ClusterClient.py -m -f Data/tie.wrl 127.0.0.1:30000 127.0.0.1:30001
# 
# The client will open an emoty window that you can use to navigate. The
# display is shown in the server windows.
#
# This will run all three on the same machine, but you can also start the 
# servers anywhere else, as long as you can reach them via multicast.
#
# Note: This will run two VERY active OpenGL programs on one screen. Not all
# OpenGL drivers are happy with that, so if it crashes your X, it's not our
# fault! ;)

import osg2 as osg
from OpenGL.GL import *
from OpenGL.GLUT import *


# Global scene manager reference.
mgr = None

# ============================================================================
# GLUT callback functions.
# ============================================================================

def display():
   mgr.redraw()

   osg.Thread.getCurrentChangeList().clear()

   glClear(GL_COLOR_BUFFER_BIT)
   glutSwapBuffers()

def reshape(w, h):
   glutPostRedisplay()

def mouse(button, state, x, y):
   if state:
      mgr.mouseButtonRelease(button, x, y)
   else:
      mgr.mouseButtonPress(button, x, y)

   glutPostRedisplay()

def motion(x, y):
   mgr.mouseMove(x, y)
   glutPostRedisplay()

def keyboard(k, x, y):
   if ord(k) == 27:
      sys.exit(0)

# ============================================================================
# Main function
# ============================================================================

def main():
   scene = None

   args = sys.argv[1:]
   osg.osgInit(sys.argv)

   glutInit(sys.argv)
   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE)

   winid = glutCreateWindow("PyOpenSG Navigator")

   glutReshapeFunc(reshape)
   glutDisplayFunc(display)
   glutMouseFunc(mouse)
   glutMotionFunc(motion)
   glutKeyboardFunc(keyboard)

   mwin = osg.MultiDisplayWindow.create()

   while len(args) > 0:
      arg = args.pop(0)

      if arg.startswith('-'):
         if arg[1] == 'm':
            mwin.setConnectionType('Multicast')
            print "Connection type set to Multicast"
         elif arg[1] == 'p':
            mwin.setConnectionType('SockPipeline')
            print "Connection type set to SockPipeline"
         elif arg[1] == 'i':
            try:
               if len(arg) > 2:
                  opt = arg[2:]
               else:
                  opt = args.pop(0)
            except:
               opt = None

            if opt:
               mwin.setConnectionInterface(opt)
         elif arg[1] == 'a':
            try:
               if len(arg) > 2:
                  opt = arg[2:]
               else:
                  opt = args.pop(0)
            except:
               opt = None

            if opt:
               mwin.setServiceAddress(opt)
         elif arg[1] == 'f':
            try:
               if len(arg) > 2:
                  opt = arg[2:]
               else:
                  opt = args.pop(0)
            except:
               opt = None

            if opt:
               scene = osg.SceneFileHandler.the().read(opt)
         elif arg[1] == 'x':
            try:
               if len(arg) > 2:
                  opt = arg[2:]
               else:
                  opt = args.pop(0)
            except:
               opt = None

            if opt:
               mwin.setHServers(int(opt))
         elif arg[1] == 'y':
            try:
               if len(arg) > 2:
                  opt = arg[2:]
               else:
                  opt = args.pop(0)
            except:
               opt = None

            if opt:
               mwin.setVServers(int(opt))
      else:
         print arg
         mwin.pushToServers(arg)

   # Dummy size for navigator.
   mwin.setSize(300, 300)

   if scene is None:
      scene = osg.makeTorus(0.5, 2, 16, 16)

   osg.commitChanges()

   global mgr
   mgr = osg.SimpleSceneManager()

   # Tell the scene manager what to manage.
   mgr.setWindow(mwin)
   mgr.setRoot(scene)

   # Show the whole scene.
   mgr.showAll()

   # Initialize the window.
   mwin.init()

   glutMainLoop()

   sys.exit(0)

if __name__ == '__main__':
   main()
